Dart _fe_analyzer_shared scanner AbstractScanner tokenize

tokenize 主要任务是将输入的源代码转换为一个词素流,AbstractScanner 类最核心方法。

调用处

全局搜索调用 tokenize() 的地方,就能知道全局在哪里启动了编译的初步流程。

以上代码中,省略了各个 test 目录下的代码。

代码实现

@override
Token tokenize() {
  // 首先,它进入一个循环
  // 只要没有到达文件的末尾,就会继续执行循环。
  while (!atEndOfFile()) {
	// 在每次循环中,它首先调用 
	// `advance` 方法来获取下一个字符。
    int next = advance();

	// 然后,它会检查是否已经读取到文件的末尾。
    // Scan the header looking for a language version
    if (!identical(next, $EOF)) {
      // 如果没有
      Token oldTail = tail;
      // 它会调用 `bigHeaderSwitch` 方法
      // 来处理文件头部的语言版本信息。
      next = bigHeaderSwitch(next);
      // 如果读取到的字符是脚本词素
      if (!identical(next, $EOF) && tail.kind == SCRIPT_TOKEN) {
        // 它会再次调用 `bigHeaderSwitch` 方法。
        oldTail = tail;
        next = bigHeaderSwitch(next);
      }
      // 然后,只要没有读取到文件的末尾,并且最后一个词素没有改变,
      // 它会继续调用 `bigHeaderSwitch` 方法。
      while (!identical(next, $EOF) && tail == oldTail) {
        next = bigHeaderSwitch(next);
      }
      next = next;
    }
	// 接下来,只要没有读取到文件的末尾
	// 它会调用 `bigSwitch` 方法来处理剩余的字符。
    while (!identical(next, $EOF)) {
      next = bigSwitch(next);
    }
    // 如果已经读取到文件的末尾
    // 它会调用 `appendEofToken` 方法
    // 来添加一个表示文件结束的词素。
    if (atEndOfFile()) {
      appendEofToken();
    } else {
      // 否则,它会调用 `unexpectedEof` 方法
      // 来处理意外的文件结束。
      unexpectedEof();
    }
  }

  // 在循环结束后,它会将字符串偏移量加一并添加到行开始的列表中,
  // 这是为了模拟文件末尾的行。
  // Always pretend that there's a line at the end of the file.
  lineStarts.add(stringOffset + 1);

  // 最后,它会调用 `firstToken` 方法来返回词素流的第一个词素。
  return firstToken();
}

类属性


本文作者:Maeiee

本文链接:Dart _fe_analyzer_shared scanner AbstractScanner tokenize

版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!


喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!